package cms.web.filter;

import cms.bean.user.AccessUser;
import cms.bean.user.User;
import cms.bean.user.UserState;
import cms.service.user.UserService;
import cms.utils.Base64;
import cms.utils.SpringContextHolder;
import cms.utils.WebUtil;
import cms.utils.threadLocal.AccessUserThreadLocal;
import cms.manage.user.UserManage;
import cms.web.taglib.Configuration;
import cms.web.util.WsWebSessionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.queryString.util.MultiMap;
import org.queryString.util.UrlEncoded;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 检查登录用户跳转
 *
 */
@Slf4j
public class LoginFilter implements Filter {
	
	public void destroy() {

	}

	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		boolean isJump = false;

		AccessUser accessUser = AccessUserThreadLocal.get(request.getSession(), false);
		log.info("用户信息={}",accessUser);
		if (accessUser != null) {
			UserManage userManage = SpringContextHolder.getBean("userManage");
			UserState userState = userManage.queryUserState(accessUser.getUserName().trim());//用户状态
			if (userState != null) {
				if (ObjectUtils.notEqual(userState.getSecurityDigest(),accessUser.getSecurityDigest())) {//如果安全摘要有改变
					isJump = true;
				}else if (userState.getState() != 1) {// 如果不是正常用户   1:正常用户
					isJump = true;
				}
			} else {
				isJump = true;
			}
		}else {
			Long uid = WsWebSessionUtil.getUid(request.getSession(), false);
			log.info("SSO登录信息，uid={}",uid);
			if (uid != null) {//已登录
				User user = SpringContextHolder.getBean(UserService.class).findUserById(uid);
				log.info("SSO登录成功信息，user={}",user);
				if (user != null) {
					accessUser = new AccessUser(user.getId(), user.getUserName(), user.getNickname(), user.getAvatarPath(), user.getAvatarName(), user.getSecurityDigest(), false, "0");
					//数据已同步
					AccessUserThreadLocal.set(accessUser);
				}
			}
			isJump = true;
		}
		
		
		
		boolean isAjax = WebUtil.submitDataMode(request);
		if(isJump == true){
			
			String uri = request.getRequestURI();
			//获取URI后面的参数
			if(request.getQueryString() != null && !"".equals(request.getQueryString())){
				uri += "?"+request.getQueryString();
			}
			
			String jumpUrl = "";
			
			
			if(uri != null){
				
				if("POST".equals(request.getMethod())){
					String referer= request.getHeader("referer");
					if(referer != null && !"".equals(referer)){
						uri = StringUtils.removeStartIgnoreCase(referer,Configuration.getUrl(request));//移除开始部分的相同的字符,不区分大小写
					}
				}else{
					if(isAjax == true){//ajax方式提交
						String url_jumpUrl = request.getParameter("jumpUrl");
						
						if(url_jumpUrl != null && !"".equals(url_jumpUrl.trim())){//如果jumpUrl参数已经有值
							jumpUrl = url_jumpUrl;
							
						}else{
							String referer= request.getHeader("referer");  
							if(referer != null && !"".equals(referer)){
								uri = StringUtils.removeStartIgnoreCase(referer,Configuration.getUrl(request));//移除开始部分的相同的字符,不区分大小写
								if(uri != null && !"".equals(uri.trim())){
									//截取问号之后的字符
									String referer_queryString = StringUtils.substringAfter(uri, "?");//从左往右查到相等的字符开始，保留后边的，不包含等于的字符
									String referer_url_jumpUrl = this.getJumpUrl(referer_queryString);
									if(referer_url_jumpUrl != null && !"".equals(referer_url_jumpUrl.trim())){//如果jumpUrl参数已经有值
										jumpUrl = referer_url_jumpUrl;
										
									}
								}
							}
							
						}
						
						
					}else{
						String contextPath = request.getContextPath();
						
						// 删除虚拟目录
						if(contextPath != null && !"".equals(contextPath)){
							int old_uri_length = uri.length();
							
							uri = StringUtils.removeStartIgnoreCase(uri,contextPath+"/");//移除开始部分的相同的字符,不区分大小写 如shop/
							
							if(uri != null && old_uri_length != uri.length()){
								uri = StringUtils.removeStartIgnoreCase(uri,"/"+contextPath+"/");//移除开始部分的相同的字符,不区分大小写 如/shop/
							}
							
						}else{
							//删除开头的左斜杆
							uri = StringUtils.removeStartIgnoreCase(uri,"/");//移除开始部分的相同的字符,不区分大小写
						}
					}
					
				}
				
			}
			if("".equals(jumpUrl) && uri != null && !"".equals(uri.trim())){
				jumpUrl = Base64.encodeBase64URL(uri);//Base64安全编码
			}
			if(isAjax == true) {//ajax方式提交
				String newJumpUrl = "login?jumpUrl=" + jumpUrl;
				response.setHeader("jumpPath", newJumpUrl);//设置登录页面响应http头。用来激活Ajax请求处理方式 Session超时后的跳转

				//如果在登录页面使用Ajax请求/user/开头的URL,出现死循环
				if (newJumpUrl.equals(uri)) {
					response.setStatus(508);//508服务器处理请求时检测到一个无限循环
					return;
				}
			}else{
				String contextPath = request.getContextPath();
				response.sendRedirect((contextPath != null && !"".equals(contextPath.trim()) ? contextPath+"/" : "/")+"login?jumpUrl="+jumpUrl);
			}
			
			return;
		}
		
		chain.doFilter(req, res);
	}

	public void init(FilterConfig arg0) throws ServletException {


	}

	/**
	 * 获取跳转参数
	 * @param queryString
	 * @return
	 */
	private String getJumpUrl(String queryString){
		if(queryString != null && !"".equals(queryString)){
       		MultiMap<String> values = new MultiMap<String>();  
	       	UrlEncoded.decodeTo(queryString, values, "UTF-8");
	       	Iterator iter = values.entrySet().iterator();  
	       	while(iter.hasNext()){  
	       		Map.Entry e = (Map.Entry)iter.next();  
	       		if("jumpUrl".equals(e.getKey()) && e.getValue() != null){
	       			if(e.getValue() instanceof List){
	       				List<String> valueList = (List)e.getValue();
		       			if(valueList.size() >0){
		       				for(String value :valueList){
		       					if(value != null && !"".equals(value.trim())){
		       						return value.trim();
		       					}
		       				}
			       		}
		       		}
	       		}
	       	} 
       	}
		return null;
	}
}
